﻿using System;
using System.Windows.Media;
using Elca.MvvmHelpers;

namespace ULSDeobfuscator {

    public static class DateTimeExtension {
        
        /// <summary>
        /// Shows lots of details of a date
        /// </summary>
        /// <param name="dt">Date to display</param>
        /// <returns>a culture-dependent string with lots of details</returns>
        public static string ToDisplayString(this DateTime dt) {

            return dt.ToShortDateString() + dt.ToString(" HH:mm:ss:ff");
        }
        /// <summary>
        /// Shows lots of details of a date, but not the ms in order to be parsable
        /// </summary>
        /// <param name="dt">Date to display</param>
        /// <returns>a culture-dependent string with lots of details</returns>
        public static string ToDisplayParsableString(this DateTime dt) {

            return dt.ToShortDateString() + dt.ToString(" HH:mm:ss");
        }
    }

    /// <summary>
    /// A log entry.
    /// </summary>
    /// <remarks>
    /// This class shamelessly mixes Model and ViewModel stuff...
    /// </remarks>
    public class LogEntry : BaseNotifyableObject {

        // data found in log file
        public DateTime Day { get; set; }

        public string DisplayedDay {
            get { return Day.ToDisplayString(); }
        }

        // a color rule may access this field, with the Contains method call => cannot be null
        private string _message = String.Empty;
        public string Message {
            get { return _message; }
            set {
                _message = value;
                LowerCaseMessage = _message.ToLowerInvariant();
            }
        }

        public string LowerCaseMessage { get; set; }
        public string Process { get; set; }
        public string ProcessInformation { get; set; }
        public string Tid { get; set; }
        public string Area { get; set; }
        public string Category { get; set; }
        public string EventID { get; set; }
        public string Level { get; set; }

        // should be a Guid, but we don't really use this info
        // same remark as Message about nullness
        private string _correlation = String.Empty;
        public string Correlation {
            get { return _correlation; }
            set {
                _correlation = value;
                LowerCaseCorrelation = (_correlation == null) ? String.Empty : _correlation.ToLowerInvariant();
            }
        }

        public string LowerCaseCorrelation { get; set; }

        // Version 1.12: this has been removed as SP sometimes does not include the continuation markers (at the beginning or at the end of a line)
        // We now try to complete a message that has the same timestamp and thread id
//        /// <summary>
//        /// are we waiting for some parts of the message ?
//        /// </summary>
//        public bool IsComplete { get; set; }

        /// <summary>
        /// Are the background and foreground brushes computed ?
        /// </summary>
        public bool AreBrushesSet { get; set; }

        private SolidColorBrush _foregroundBrush;
        public SolidColorBrush ForegroundBrush {
            get { return _foregroundBrush; }
            set {
                if (!Equals(_foregroundBrush, value)) {
                    _foregroundBrush = value;
                    OnPropertyChanged("ForegroundBrush");
                }
            }
        }

        private SolidColorBrush _backgroundBrush;
        public SolidColorBrush BackgroundBrush {
            get { return _backgroundBrush; }
            set {
                if (!Equals(_backgroundBrush, value)) {
                    _backgroundBrush = value;
                    OnPropertyChanged("BackgroundBrush");
                }
            }
        }

        private bool _isMessageParsed;
        public string ParsedMessage {
            get {

                if (!_isMessageParsed) {

                    ParseMessage();
                    _isMessageParsed = true;
                }
                return Message;
            }
        }

        public bool IsMultiLine { get; set; }

        public bool HasAnnotation => Annotation != null;

        /// <summary>
        /// Line number relative to the all files loaded (i.e. this is the 'real' line number only for the first file)
        /// </summary>
        public int LineNumber { get; set; }

        public AnnotationInfo Annotation { get; set; }

        private void ParseMessage() {

            Message = Message.Replace("   at", Environment.NewLine + "at");
        }
    }
}
